#include <git2.h>
#include <stdio.h>
#include <string.h>

typedef struct ref_name_arr {
	uint count;
	char strings[64][64];
};

typedef struct submodule_name_arr {
	uint count;
	char strings[64][64];
};

static int get_ref_name_cb(const char *refname, void *payload);
static int get_submodule_name_cb(git_submodule *sm, const char *name, void *payload);

int main() {
	git_libgit2_init();
	char *repo_path = "test_repos";
	git_repository *repo;
	int ret = git_repository_open(&repo ,repo_path);
	if(ret<0) {
		printf("git_repository_open failed, error msg:%s\n", giterr_last()->message);
	}
	printf("open ok\n");

	int error, i;

	printf("repository ref_names:\n");
	git_strarray ref_names;
	git_reference_list(&ref_names, repo);
	for (i = 0; i < ref_names.count; ++i) {
		printf("%s\n", ref_names.strings[i]);
	}
	git_strarray_free(&ref_names);

	printf("repository foreach ref_names:\n");
	struct ref_name_arr refs_arr;
	bzero(&refs_arr, sizeof(struct ref_name_arr));
	git_reference_foreach_name(repo, get_ref_name_cb, &refs_arr);
	for(i=0; i<refs_arr.count; ++i) {
		printf("%s\n", refs_arr.strings[i]);
	}

	printf("repository iterator ref_names:\n");
	git_reference_iterator *it;
	git_reference *ref;
	git_reference_iterator_new(&it, repo);
	while ((error = git_reference_next(&ref, it)) == 0) {
		printf("%s\n", git_reference_name(ref));
		git_reference_free(ref);
	}
	git_reference_iterator_free(it);

	git_branch_iterator *iter;
	git_branch_t branch_type;

	printf("repository local branch_names:\n");
	git_branch_iterator_new(&iter, repo, GIT_BRANCH_LOCAL);
	while ((error = git_branch_next(&ref, &branch_type, iter)) == 0) {
		printf("%s\n", git_reference_name(ref));
		git_reference_free(ref);
	}
	git_branch_iterator_free(iter);

	printf("repository remote branch_names:\n");
	git_branch_iterator_new(&iter, repo, GIT_BRANCH_REMOTE);
	while ((error = git_branch_next(&ref, &branch_type, iter)) == 0) {
		printf("%s\n", git_reference_name(ref));
		git_reference_free(ref);
	}
	git_branch_iterator_free(iter);

	printf("repository tag_names:\n");
	git_strarray tag_names;
	git_tag_list(&tag_names, repo);
	for (i = 0; i < tag_names.count; ++i) {
		printf("%s\n", tag_names.strings[i]);
	}
	git_strarray_free(&tag_names);

	//head
	git_reference *head;
	git_repository_head(&head, repo);
	printf("repository head: %s\n", git_reference_name(head));
	git_reference_free(head);

	//remote
	printf("repository remote_names:\n");
	git_strarray remote_names;
	git_remote_list(&remote_names, repo);
	for (i = 0; i < remote_names.count; ++i) {
		printf("%s\n", remote_names.strings[i]);
	}
	git_strarray_free(&remote_names);

	//submodule
	struct submodule_name_arr sb_arr;
	bzero(&sb_arr, sizeof(struct submodule_name_arr));
	git_submodule_foreach(repo, get_submodule_name_cb, &sb_arr);
	for (i = 0; i < sb_arr.count; ++i) {
		printf("%s\n", sb_arr.strings[i]);
	}

	git_repository_free(repo);
	return 0;
}

static int get_ref_name_cb(const char *refname, void *payload) {
	// printf("get_ref_name_cb:%s\n", refname);
	struct ref_name_arr *refs_name = (struct ref_name_arr *)payload;
	memcpy(refs_name->strings[refs_name->count++], refname, 64);
}

static int get_submodule_name_cb(git_submodule *sm, const char *name, void *payload) {
	// printf("get_ref_name_cb:%s\n", refname);
	struct submodule_name_arr *sb_name = (struct submodule_name_arr *)payload;
	memcpy(sb_name->strings[sb_name->count++], name, 64);
}
